/*
	libsimple_support - a mess of C++ utility code
	https://notabug.org/namark/libsimple_support
	https://gitlab.com/namark/libsimple_support
	https://github.com/namark/libsimple_support

	Copyright (C) 2017-2019 respective authors/contributors

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SIMPLE_SUPPORT_FUNCTION_UTILS_HPP
#define SIMPLE_SUPPORT_FUNCTION_UTILS_HPP
#include <type_traits>
#include <tuple>

namespace simple { namespace support
{

	template <typename Function>
	struct fun_signature;

	template <typename ReturnType, typename... ArgumentType>
	struct fun_signature<ReturnType(ArgumentType...)>
	{
		using return_type = ReturnType;
		using argument_type = std::tuple<ArgumentType...>;
	};

	template <typename Function, int param_index = 0>
	struct fun_param
	{
		using type = std::tuple_element_t<param_index, typename fun_signature<Function>::argument_type>;
	};

	template <typename Function, int param_index = 0>
	using fun_param_t = typename fun_param<Function, param_index>::type;

	template <typename Function>
	using fun_return_t = typename fun_signature<Function>::return_type;

	template <typename ReturnType, typename... ArgumentType>
	inline constexpr ReturnType nop(ArgumentType...) {}

	template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
	template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

}} // namespace simple.support

#endif /* end of include guard */
